
/**
 *  \file avctp_internal.h
 *
 *  This is internal header file of AVCTP module. This file contains the Data
 *  Types, Type Definitions, Macros, Constant Definitions, and Function
 *  Declarations that the AVCTP implementation uses internally.
 */

/*
 *  Copyright (C) 2013. Mindtree Ltd.
 *  All rights reserved.
 */

#ifndef _H_AVCTP_INTERNAL_
#define _H_AVCTP_INTERNAL_

/* ------------------------- Header File Inclusion */
/* EtherMind Common Header Files */
#include "BT_common.h"

/* AVCTP API & Module Header Files */
#include "BT_avctp_api.h"
#include "avctp.h"

/* For PSM structure and L2CAP APIs */
#include "l2cap.h"

/* For the Write Task & Bottom Halves */
#include "write_task.h"
#include "BT_bottom_half.h"


/* ------------------------- AVCTP Debug Macros */
#ifndef AVCTP_NO_DEBUG
#define AVCTP_ERR(...)                                BT_debug_error(BT_MODULE_ID_AVCTP, __VA_ARGS__)
#else  /* AVCTP_NO_DEBUG */
#define AVCTP_ERR                                     BT_debug_null
#endif /* AVCTP_NO_DEBUG */

#ifdef AVCTP_DEBUG

#define AVCTP_TRC(...)                                BT_debug_trace(BT_MODULE_ID_AVCTP, __VA_ARGS__)
#define AVCTP_INF(...)                                BT_debug_info(BT_MODULE_ID_AVCTP, __VA_ARGS__)

#else /* AVCTP_DEBUG */

#define AVCTP_TRC                                     BT_debug_null
#define AVCTP_INF                                     BT_debug_null

#endif /* AVCTP_DEBUG */


/* ------------------------- Global Definitions */

/** AVCTP Control Packet Types */
#define AVCTP_CTR_PKT_SINGLE                          0x00
#define AVCTP_CTR_PKT_START                           0x04
#define AVCTP_CTR_PKT_CONTINUE                        0x08
#define AVCTP_CTR_PKT_END                             0x0C

/** Bitmap mask for AVCTP Signaling Channel State */
#define AVCTP_MASK_CONNECTION_IN_PROGRESS             0x01
#define AVCTP_MASK_CONFIGURATION_IN_PROGRESS          0x02
#define AVCTP_MASK_REMOTE_CONF_COMPLETED              0x04
#define AVCTP_MASK_LOCAL_CONF_COMPLETED               0x08
#define AVCTP_MASK_CONNECTED                          0x10
#define AVCTP_MASK_LOCAL_CONFIGURATION_INITIATED      0x20

/** Bitmap mask for Remote and Local Configuration complete */
#define AVCTP_MASK_LOCAL_REMOTE_CONF_COMPLETED        0x0C
#define AVCTP_MASK_REMOTE_COMPLETE_LOCAL_NOT_COMPLETE 0x04

/** Mask values used for AVCTP Control Packet Header */
#define AVCTP_MASK_CTR_PT                             0x0C
#define AVCTP_MASK_CTR_MT                             0x02
#define AVCTP_MASK_CTR_TL                             0xF0
#define AVCTP_MASK_CTR_TL_MT                          0xF2
#define AVCTP_MASK_CTR_IPID                           0x01
#define AVCTP_CTR_TL_BIT_OFFSET                       4

/** Header length of AVCTP Control Packets */
#define AVCTP_PKT_HDR_SIZE_START                      4
#define AVCTP_PKT_HDR_SIZE_SINGLE                     3
#define AVCTP_PKT_HDR_SIZE_CON_OR_END                 1

/** AVCTP Misc Constants */
#define AVCTP_INVALID_OPERATION                       0x00
#define AVCTP_INVALID_PROFILE_ID                      0x0000
#define AVCTP_INVALID_LCID                            0x0000
#define AVCTP_ALLOCATED_LCID                          0x0001
#define AVCTP_CTR_MSG_IPID_BIT_SET                    0x01
#define AVCTP_CONNECT_REQ_INITIATOR                   0x01

/** AVCTP Channel set / reset return values */
#define AVCTP_COMMAND_CHANNEL_SET                     0x01
#ifdef AVCTP_1_3
#define AVCTP_BROWSING_CHANNEL_SET                    0x02
#endif /* AVCTP_1_3 */
#define AVCTP_COMMAND_CHANNEL_RESET                   0x03
#ifdef AVCTP_1_3
#define AVCTP_BROWSING_CHANNEL_RESET                  0x04
#endif /* AVCTP_1_3 */


/* ------------------------- Macros */

/** AVCTP Dynamic Memory Allocation and Release macros. */
#define avctp_malloc            BT_alloc_mem
#define avctp_free              BT_free_mem


/** Lock AVCTP Mutex */
#define avctp_lock()              BT_MUTEX_LOCK(avctp_mutex, AVCTP)

/** Unlock AVCTP Mutex */
#define avctp_unlock()            BT_MUTEX_UNLOCK(avctp_mutex, AVCTP)

/** Lock AVCTP Mutex */
#define avctp_lock_void()         BT_MUTEX_LOCK_VOID(avctp_mutex, AVCTP)

/** Unlock AVCTP Mutex */
#define avctp_unlock_void()       BT_MUTEX_UNLOCK_VOID(avctp_mutex, AVCTP)

/** To find the minimum of two values */
#define AVCTP_MIN(a, b)  ((a) < (b) ? (a) : (b))

/** To set/get/reset a Bit in AVCTP Bitmaps */
#define AVCTP_SET_BIT(bitmap, mask)     ((bitmap) |= (mask))
#define AVCTP_GET_BIT(bitmap, mask)     (((bitmap) & (mask)) == (mask))
#define AVCTP_RESET_BIT(bitmap, mask)   ((bitmap) ^= (mask))

/** To pack the Profile Identfier into the AVCTP control packet header */
#define AVCTP_PACK_PID(buf, pid)         \
    *((buf) + 0) = (UCHAR) ((pid) >> 8); \
    *((buf) + 1) = (UCHAR) (pid)

/** To unpack the Profile Identfier into the AVCTP control packet header */
#define AVCTP_UNPACK_PID(buf, pid)   \
    pid =  (UCHAR) *((buf) + 0);     \
    pid =  (UINT16) (pid << 8);      \
    pid |= (UINT16) *((buf) + 1)

/**
 *  This utility macro sets Profile and Signaling Channel
 *  Indices of AVCTP HANDLE.
 *
 *  \param hdl (IN)
 *         The AVCTP Handle to be initialized.
 *  \param p_index (IN)
 *         Profile Index.
 *  \param ctrl_ch_index (IN)
 *         Control Channel Index.
 *  \param brow_ch_index (IN)
 *         Browsing Channel Index.
 *
 *  \hideinitializer
 */
#define AVCTP_SET_HANDLE(hdl, p_index, ctrl_ch_index, brow_ch_index) \
        ((hdl).profile_index) = (p_index);                           \
        ((hdl).ctrl_ch_index) = (ctrl_ch_index);             \
        ((hdl).brow_ch_index) = (brow_ch_index)

#ifdef AVCTP_CHECK_BROWSING_CH_MTU
#define AVCTP_BROWSING_CH_MIN_MTU_CHECK(si, mtu, lcid) \
    { \
        UCHAR channel_type; \
 \
        /* Get AVCTP Channel type */ \
        channel_type = avctp_get_channel_type ((si)); \
 \
        /* Check for Minimum MTU size */ \
        if ((channel_type == AVCTP_CHANNEL_TYPE_BROWSING) && \
            ((mtu) < AVCTP_DEFAULT_BROW_CH_L2CAP_MTU)) \
        { \
             AVCTP_ERR( \
             "[AVCTP]Invalid AVCTP Browsing Channel MTU :%d \n", (mtu)); \
 \
            /* Disconnect L2CAP Channel */ \
            l2ca_disconnect_req ((lcid)); \
 \
            /* Unlock AVCTP */ \
            avctp_unlock(); \
 \
            return API_SUCCESS; \
        } \
    }
#else
#define AVCTP_BROWSING_CH_MIN_MTU_CHECK(si, mtu, lcid)
#endif /* AVCTP_CHECK_BROWSING_CH_MTU */


/* ------------------------- Internal Structures/Data Types */

/**
 *  \struct AVCTP_SIGCH
 *  \brief  This table is used to store information related to the  AVCTP
 *          Signaling Channel to a peer AVCTP Entity.
 *
 *  This table is used to store information related to the AVCTP Signaling
 *  Channel to a peer AVCTP Entity. There shall be only one Signaling Channel
 *  between a pair of AVCTP Entities.
 *
 *  \note
 *  \li    An entry from this table is allocated when the following occurs:
 *          - When AVCTP Signaling Channel establishment request is received
 *            from the application and there exists no AVCTP Signaling Channel
 *            to the specified remote device (AVCTP Entity).
 *
 *          - When L2CAP connection indication is received from a Bluetooth
 *            Device Address (BD_ADDR) for which there exists no AVCTP
 *            Signaling Channel.
 *
 *  \li    An entry from this table is de-allocated (destroyed) when
 *         the following occurs:
 *          - When AVCTP Signaling Channel disconnection request is received
 *            from the application.
 *
 *          - When L2CAP disconnection indication is received for a L2CAP CID
 *            belonging to an AVCTP Signaling Channel to a remote AVCTP Entity
 *            (BD_ADDR).
 *
 *  \li    An entry in this table is free for use if the l2cap_cid is set to
 *         AVCTP_INVALID_LCID.
 *
 *  \li    An entry in this table can be uniquely searched using the following
 *         parameters:
 *          - Using the Bluetooth Device Address (BD_ADDR) of the remote AVCTP
 *            Entity.
 *          - Using the L2CAP channel Identifier (CID).
 *
 */
typedef struct
{
    /**
     *  This is buffer allocated to store segments of fragmented AVCTP
     *  command/response packets before it is reassembled completely.
     */
    UCHAR * reasm_buffer;

    /** This is current length of the AVCTP signaling reassembly buffer.*/
    UINT16 reasm_buffer_len;

    /**
     *  This is length of fragmented AVCTP command/response packet expected
     *  in the subsequent segments of fragmented AVCTP command/response
     *  packets.
     */
    UINT16 reasm_len_expected;

    /**
     *  This is the maximum amount of data that can be sent over this AVCTP
     *  Signaling Channel in one L2CAP packet.
     */
    UINT16 l2cap_out_mtu;

    /** This is the L2CAP Channel ID for this Signaling Channel. */
    UINT16 l2cap_cid;

    /** This is Profile Entity Index of the packet being reassembled. */
    UCHAR reasm_pi;

    /** This is number of AVCTP command/response packet segments expected. */
    UCHAR reasm_num_expected;

    /**
     *  This is a Transaction Label and Message Type of AVCTP command/response
     *  packets being reassembled. Here
     *      bit 0, bit 1: Message Type.
     *      bit 4, bit 5, bit 6, bit 7: Transaction Label.
     */
    UCHAR reasm_tl_mt;

    /**
     *  This is the state of the L2CAP Channel for this Signaling Channel.
     *  This element is a bitmap; meaning of each bit is given below.
     *      Bit 0: Connection in progress
     *      Bit 1: Configuration in progress
     *      Bit 2: Remote configuration completed
     *      Bit 3: Local configuration completed
     *      Bit 4: Connected
     *      Bit 5: Local configuration initiated
     */
    UCHAR channel_state;

    /**
     *  This is the flag, which is set to "1" when AVCTP Signaling Channel
     *  establishment request is received from application on this Signaling
     *  Entity.
     */
    UCHAR initiator;

    /**
     *  This is Remote Bluetooth Device Address for this AVCTP Signaling
     *  Channel.
     */
    DEVICE_HANDLE   handle;

    /**
     *  This flag holds the type of Signaling Entity.
     *
     *  Possible Types: AVCTP_CHANNEL_TYPE_COMMAND,
     *  AVCTP_CHANNEL_TYPE_BROWSING and AVCTP_CHANNEL_TYPE_INVALID.
     */
    UCHAR channel_type;

    /**
     * This is an index to associated AVCTP Profile Entity.
     */
    UCHAR profile_entity_index;

    /**
     *  This identifies the AVCTP API (User Operation) that has requested an
     *  operation on this Signaling Channel. This is set to AVCTP_CONNECT_CNF
     *  incase of BT_avctp_connect_req and AVCTP_DISCONNECT_CNF in case of
     *  BT_avctp_disconnect_req
     */
    UCHAR operation;

} AVCTP_SIGCH;



/**
 *  \struct AVCTP_PROFILE_ENTITY
 *  \brief  This table is used to store information related to an AVCTP Profile.
 *
 *  This table is used to store information related to an AVCTP Profile.
 *
 *  \note
 *  \li    An entry from this table is allocated when the following occurs:
 *          - When a profile is registered to AVCTP by the application/profile.
 *
 *  \li    An entry from this table is de-allocated (destroyed) when the
 *         following occurs:
 *          - When a profile is de-registered from AVCTP by the
 *            application/profile.
 *
 *  \li    An entry in this table is free for use if the profile_id is set to
 *         AVCTP_INVALID_PROFILE_ID..
 *
 *  \li    An entry in this table can be uniquely searched under the following
 *         conditions:
 *          - Using the Profile Identifier and the Signaling Channel index.
 */
typedef struct
{
    /**
     *  This is callback function pointer, which needs to be called when
     *  AVCTP needs to inform events like AVCTP connection confirmation
     *  AVCTP message reception for this profile.
     */
    AVCTP_EVENT_NTF_CB event_ntf_cb;

    /**
     *  This is maximum packet size value for the command/response, which this
     *  profile can receive in one L2CAP packet.
     */
    UINT16 in_mtu;

    /**
     *  This is the flush timeout value, which this profile has requested for
     *  data retransmission.
     */
    UINT16 flush_to;

    /** This is Profile Identifier of this profile. */
    UINT16 profile_id;

} AVCTP_PROFILES;


/**
 *  \struct AVDTP_SEND_MESSAGE_BH_PARAMS
 *  \brief  The BottomHalf parameters for the AVCTP Send Message Request.
 *
 *  The BottomHalf parameters for the AVCTP Send Message Request.
 *
 *  \note
 *
 */
typedef struct
{
    /** AVCTP Control Message */
    UCHAR * packet;

#ifdef HAVE_AVRCP_MSG_COPY
    /** Pointer to AVRCP message buffer allocated in the AVCTP Layer */
    UCHAR * avrcp_msp_copy_ptr;
#endif /* HAVE_AVRCP_MSG_COPY */

    /** Size of AVCTP Control Message */
    UINT16 packet_len;

    /** AVCTP Handle */
    AVCTP_HANDLE handle;

    /** AVCTP channel over which the command is packet is to be sent */
    UCHAR  channel;

} AVCTP_SEND_MESSAGE_BH_PARAMS;

/**
 *  \struct AVDTP_SEND_DISCONNECT_BH_PARAMS
 *  \brief  The BottomHalf parameters for the AVCTP Disconnect Request.
 *
 *  The BottomHalf parameters for the AVCTP Send Disconnect Request.
 *
 *  \note
 *
 */
typedef struct
{
    /** AVCTP Handle */
    AVCTP_HANDLE handle;

    /** AVCTP channel over which the command is packet is to be sent */
    UCHAR  channel;

} AVCTP_SEND_DISCONNECT_BH_PARAMS;

/**
 *  \struct AVDTP_SEND_CONNECT_BH_PARAMS
 *  \brief  The BottomHalf parameters for the AVCTP Connect Request.
 *
 *  The BottomHalf parameters for the AVCTP Send Connect Request.
 *
 *  \note
 *
 */
typedef struct
{
    /** AVCTP Handle */
    AVCTP_HANDLE handle;

    /** AVCTP channel over which the command is packet is to be sent */
    UCHAR  channel;

} AVCTP_SEND_CONNECT_BH_PARAMS;


/* ------------------------- Internal Function Declarations */


/* ------------------------- L2CAP Connection and Disconnection Functions */

/*
 *  This is a callback function for the incoming
 *  connect request from the peer device.
 */
API_RESULT avctp_l2ca_connect_ind
           (
               /* IN */  DEVICE_HANDLE    * handle,
               /* IN */  UINT16           lcid,
               /* IN */  UINT16           psm
           );

/*
 *  This is a callback function for the incoming
 *  connect response for the connect request sent.
 */
API_RESULT avctp_l2ca_connect_cnf
           (
               /* IN */  DEVICE_HANDLE    * handle,
               /* IN */  UINT16             lcid,
               /* IN */  UINT16             result,
               /* IN */  UINT16             status
           );

/*
 *  This is a callback function for the configuration
 *  indications.
 */
API_RESULT avctp_l2ca_config_ind
           (
               /* IN */  UINT16                 lcid,
               /* IN */  L2CAP_CONFIG_OPTION *  config_option
           );

/*
 *  This is a callback function for the incoming
 *  configuration confirmations.
 */
API_RESULT avctp_l2ca_config_cnf
           (
               /* IN */  UINT16                 lcid,
               /* IN */  UINT16                 result,
               /* IN */  L2CAP_CONFIG_OPTION *  config_option
           );

/*
 *  This function is used to ensure completion of L2CAP channel configuration.
 *  It also sends confirmation to application for channel establishment.
 */
void avctp_l2cap_procedure_complete
     (
         /* IN */  UCHAR  si
     );

/*
 *  This is a callback function for the L2CAP disconnect
 *  indication notification.
 */
API_RESULT avctp_l2ca_disconnect_ind
           (
               /* IN */  UINT16  lcid
           );

/*
 *  This is a callback function for the L2CAP disconnect
 *  confirmation notification.
 */
API_RESULT avctp_l2ca_disconnect_cnf
           (
               /* IN */  UINT16  lcid,
               /* IN */  UINT16  result
           );

/*
 *  This is a callback function registered with L2CAP for the incoming
 *  AVCTP data reception.
 */
API_RESULT avctp_l2ca_data_read
           (
               /* IN */  UINT16  lcid,
               /* IN */  UCHAR * data,
               /* IN */  UINT16  datalen
           );

/* ------------------------- AVCTP Utility Functions */

/* This function destroys the AVCTP Signaling Entity */
void avctp_destroy_sig_entity
     (
         /* IN */  UCHAR  si,
         /* IN */  UCHAR  ntf_cb_flag
     );

/*
 *  This function searches the AVCTP Signaling Entity for a remote
 *  device BD_ADDR.
 */
API_RESULT avctp_search_sig_entity
           (
               /* IN */   UCHAR            * bd_addr,
               /* IN */   DEVICE_HANDLE    * handle,
               /* IN */   UCHAR              ch_type,
               /* OUT */  UCHAR            * si
           );

/* This function searches the AVCTP Signaling Entity for a L2CAP CID. */
API_RESULT avctp_search_sig_entity_for_lcid
           (
               /* IN */  UINT16  lcid,
               /* OUT */ UCHAR * si
           );

/*
 *  This function gives notification to application about the AVCTP
 *  connection establishment.
 */
void avctp_signal_connection_complete
           (
               /* IN */ UCHAR si
           );

/*
 *  This function resets reassembly buffer of AVCTP Signaling Entity and
 *  releases the memory.
 */
void avctp_reset_sig_reasm_buffer
     (
         /* IN */  UCHAR  si
     );

/* This function handles the incoming AVCTP control message packets. */
void avctp_handle_message_packet
     (
         /* IN */  UCHAR   si,
         /* IN */  UCHAR * data,
         /* IN */  UINT16  datalen
     );

/*
 *  This function sends the AVCTP control message packet into single AVCTP
 *  packet.
 */
API_RESULT avctp_send_message_single
           (
               /* IN */  UCHAR      pi,
               /* IN */  UCHAR      si,
               /* IN */  UCHAR *    packet,
               /* IN */  UINT16     packet_len
           );

/*
 *  This function sends the AVCTP control message packet into fragmented AVCTP
 *  packets.
 */
API_RESULT avctp_send_message_fragmented
           (
               /* IN */  UCHAR      pi,
               /* IN */  UCHAR      si,
               /* IN */  UCHAR *    packet,
               /* IN */  UINT16     packet_len
           );

/*
 *  This function validates the Profile Identifier of the AVCTP Command
 *  Packet
 */
API_RESULT avctp_validate_pid
           (
               /* IN */  UINT16  profile_id,
               /* OUT */ UCHAR * pi
           );

/*
 *  This function finds the minimum value of In MTU from all the registered
 *  Profile Entity.
 */
void avctp_derive_in_mtu
     (
         /* OUT */ UINT16 * mtu
     );

/*
 *  This function sends AVCTP response message with Invalid Profile ID bit
 *  Set.
 */
API_RESULT avctp_send_response_invalid_pid
           (
               /* IN */ UCHAR  si,
               /* IN */ UCHAR  tl,
               /* IN */ UINT16 profile_id
           );

API_RESULT avctp_create_sig_channel
           (
               /* IN */  DEVICE_HANDLE    * handle,
               /* OUT */ UCHAR            * si,
               /* IN */  UCHAR            pi,
               /* IN */  UCHAR            ch_type
           );

UCHAR avctp_get_channel_type (UCHAR si);

API_RESULT avctp_connect_req
           (
               /* IN */ AVCTP_HANDLE *avctp_handle,
               /* IN */ UCHAR ch_type
           );

#ifdef AVCTP_DEBUG

    void avctp_debug_event_ntf
         (
             /* IN */  UCHAR   event_type,
             /* IN */  UCHAR   pi,
             /* IN */  UINT16  result
         );

#else  /* AVCTP_DEBUG */

    #define avctp_debug_event_ntf(a, b, c)

#endif /* AVCTP_DEBUG */


#endif /* _H_AVCTP_INTERNAL_ */


